﻿using System;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Web.Mvc;
using System.Xml;
using MvcWebScraper.Core;
using MvcWebScraper.Models;

namespace MvcWebScraper.Web
{
	public class ResponseFormatAttribute : ActionFilterAttribute
	{
		public override void OnActionExecuting(ActionExecutingContext filterContext)
		{
			var carrierAndFormat = (string)filterContext.RouteData.Values["carrier"];
			var requestCarrier = "All";
			var requestFormat = "html";
			if (!string.IsNullOrEmpty(carrierAndFormat))
			{
				var split = carrierAndFormat.Split('.');
				requestCarrier = split.Length >= 1 ? split.First() : requestCarrier;
				requestFormat = split.Length >= 2 ? split.Last() : requestFormat;
			}

			filterContext.RouteData.Values["format"] = requestFormat;
			filterContext.ActionParameters["format"] = requestFormat;

			Carrier carrier = Carrier.Unknown;
			if (Enum.GetNames(typeof(Carrier)).Any(name => name.Equals(requestCarrier, StringComparison.InvariantCultureIgnoreCase)))
				carrier = (Carrier)Enum.Parse(typeof(Carrier), requestCarrier, true);

			if (string.IsNullOrEmpty(requestCarrier))
				carrier = Carrier.All;

			filterContext.ActionParameters["carrier"] = carrier;
			base.OnActionExecuting(filterContext);
		}

		public override void OnActionExecuted(ActionExecutedContext filterContext)
		{
			var format = (string)filterContext.RouteData.Values["format"];
			if (string.IsNullOrEmpty(format) || format.Equals("html", StringComparison.InvariantCultureIgnoreCase))
				return;

			switch (format)
			{
				case "json":
					filterContext.Result = ToJson(filterContext);
					break;
				case "atom":
				case "rss":
					filterContext.Result = ToFeed(filterContext, format);
					break;
			}

			base.OnActionExecuted(filterContext);
		}

		private static JsonResult ToJson(ActionExecutedContext filterContext)
		{
			var model = ((ViewResult)filterContext.Result).ViewData.Model as MobileCIDR;
			var json = new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
			return json;
		}

		private static FeedResult ToFeed(ActionExecutedContext filterContext, string feedType)
		{
			var model = ((ViewResult)filterContext.Result).ViewData.Model as MobileCIDR;
			var feed = new SyndicationFeed();
			SyndicationFeedFormatter formatter = null;
			if (feedType == "rss")
				formatter = new Rss20FeedFormatter(feed);
			if(feedType == "atom" )
				formatter = new Atom10FeedFormatter(feed);

			var result = new FeedResult {Formatter = formatter};
			return result;
		}
	}

	public class FeedResult : ActionResult
	{
		public SyndicationFeedFormatter Formatter { get; set; }
		
		public override void ExecuteResult(ControllerContext context)
		{
			context.HttpContext.Response.ContentType =
				Formatter is Rss20FeedFormatter ? "application/rss+xml" : 
				Formatter is Atom10FeedFormatter ? "application/atom+xml" : "text/html";

			using (var writer = XmlWriter.Create(context.HttpContext.Response.OutputStream))
			{
				Formatter.WriteTo(writer);
			}
		}
	}
}
